package cc.dd.marketing.core;


import cc.dd.marketing.api.response.base.BaseResponse;
import cc.dd.marketing.core.base.BusinessHandler;
import cc.dd.marketing.core.base.RequestParser;
import cc.dd.marketing.core.base.ResponseParser;
import cc.dd.marketing.core.domain.RuleInnerDTO;
import cc.dd.marketing.common.ContextParam;
import cc.dd.marketing.rule.RuleEngine;
import cc.dd.marketing.rule.base.Rule;
import cc.dd.marketing.system.exception.response.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;

/**
 * 活动
 *
 * @author dongsufeng
 * @date 2022/9/9 2:27 PM
 */
@Slf4j
public abstract class AbstractBusinessHandler implements BusinessHandler {
    @Resource
    private CommonFactory commonFactory;
    @Resource
    private RuleEngine ruleEngine;

    @Override
    public BaseResponse handle(ContextParam contextParam) {
        beforeDoAction(contextParam);
        RequestParser requestParser = commonFactory.getBusinessReqParser(contextParam.getFunctionCode(), contextParam.getBusinessNo());
        RuleInnerDTO baseRequestDTO = requestParser.buildDTO(contextParam.getRequest(), contextParam.getBaseDTO());
        contextParam.setBaseDTO(baseRequestDTO);
        doRuleCheck(baseRequestDTO, baseRequestDTO.getRules());
        doAction(contextParam);
        return buildResponse(contextParam);
    }

    /**
     * 构造响应对象
     *
     * @param contextParam
     * @return
     */
    private BaseResponse buildResponse(ContextParam contextParam) {
        ResponseParser parser = commonFactory.getResponseParser(contextParam.getFunctionCode(),
                contextParam.getBusinessNo());

        BaseResponse buildResponse = parser.buildResponse(contextParam);
        ResultCodeEnum.SYSTEM_ERROR.assertNotNull(buildResponse);
        return buildResponse;
    }

    /**
     * 活动规则检验
     *
     * @param rules
     */
    private void doRuleCheck(RuleInnerDTO businessBaseDTO, List<Rule> rules) {
        //没有规则直接返回
        if (!businessBaseDTO.getExecute() || CollectionUtils.isEmpty(rules)) {
            return;
        }
        rules.sort(Comparator.comparing(Rule::getSort));
        ruleEngine.validate(businessBaseDTO, rules);
    }

    /**
     * 执行操作
     * 各子类自行实现，完成各种动作
     *
     * @param contextParam
     */
    protected abstract void doAction(ContextParam contextParam);

    /**
     * 前置执行操作
     * 各子类自行实现，完成各种动作
     *
     * @param contextParam
     */
    protected void beforeDoAction(ContextParam contextParam) {}

}
